﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using log4net;
using System.Net;

namespace FeiCheLiPeiTestTool
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        public List<RequestContentModel> _contentLists = new List<RequestContentModel>();

        private List<RequestContentModel> _dataLists = new List<RequestContentModel>();
        /// <summary>
        /// Main comboBox1 当前请求的地址
        /// </summary>
        public string _currentUrl = string.Empty;

        int _updateIndex = -1;

      
        private string _registerNo = string.Empty;
        private string _taskId = string.Empty;
        private string _claimNo = string.Empty;
        private string _compensateNo = string.Empty;

        private static object lockObj = new object();

        /// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            //this.Size = new Size(1140, 770);
            this.comboBox2.SelectedIndex = 0;
            this.groupBox3.Visible = false;
            this.listView1.Columns.Add("接口名", 200);
            this.listView1.Columns.Add("耗时", 100);
            this.listView1.Columns.Add("返回结果", 500);
        }

        /// <summary>
        /// 添加请求参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.comboBox1.Text) || string.IsNullOrEmpty(this.textBox2.Text))
            {
                MessageBox.Show("请求地址、接口名、请求次数？");
                return;
            }

            RequestContentForm rcf = new RequestContentForm();
            rcf._contentLists = _contentLists;
            rcf._currentUrlOfParrent = _currentUrl;
            rcf.ShowDialog();
            this.button1.Text ="添加内容"+ _contentLists.Count.ToString();
            InitListBoxData();
        }

        /// <summary>
        /// 加载数据到ListBox
        /// </summary>
        private void InitListBoxData()
        {
            this.listBox1.Items.Clear();

            foreach (var item in _contentLists)
            {
                this.listBox1.Items.Add(item.MethodName);
            }
        }

        //加载数据到CheckBoxList
        private void InitCheckBoxListData()
        {
            this.checkedListBox1.Items.Clear();
            foreach (var item in _dataLists)
            {
                this.listBox1.Items.Add(item.MethodName);
            }
        }

        /// <summary>
        /// 清空内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            _contentLists.Clear();
            _dataLists.Clear();
            this.listBox1.Items.Clear();
            this.checkedListBox1.Items.Clear();
            this.button1.Text = "添加内容0";
            this.richTextBox1.Text = "";
            this.groupBox3.Visible = false;
            this.groupBox2.Visible = true;

        }

        /// <summary>
        /// 开始请求
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
           var urlAds= this.comboBox1.Text.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries)[0];
            if (string.IsNullOrEmpty(urlAds) ||  string.IsNullOrEmpty(this.textBox2.Text))
            {
                MessageBox.Show("请求地址、接口名、请求次数？");
                return;
            }

            if (_dataLists.Count<=0)
            {
                MessageBox.Show("请求内容？");
                return;
            }

            this.label3.Text = "整体耗时0秒";

            _registerNo = string.Empty;
            _taskId = string.Empty;
            _claimNo = string.Empty;
            _compensateNo = string.Empty;

            for (int i = 0; i < this.checkedListBox1.Items.Count; i++)
            {
                _dataLists[i].IsSync = this.checkedListBox1.GetItemChecked(i);
            }

            this.listView1.Items.Clear();
            this.button3.Enabled = false;

            string _url = urlAds;
           
            int reqeustCount = int.Parse(this.textBox2.Text);

            Task.Factory.StartNew(() => DoWork(_url, reqeustCount));
        }

     
        /// <summary>
        /// 工作任务
        /// </summary>
        /// <param name="url"></param>
        /// <param name="reqeustCount"></param>
        private void DoWork(string url,int reqeustCount)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            List<Task> taskLists = new List<Task>();
            taskLists.Add(Task.Factory.StartNew((Action)delegate
            {
                for (int i = 0; i < reqeustCount; i++)
                {
                    List<Task> bathTasks = new List<Task>();
                    foreach (var item in _dataLists)
                    {
                        if (item.IsSync)
                        {
                            bathTasks.Add(Task.Factory.StartNew(() => AskApi(url, item.RequestContent, item.MethodName)));
                        }
                        else
                        {
                            AskApi(url, item.RequestContent, item.MethodName);
                        }
                    }
                    Task.WaitAll(bathTasks.ToArray());
                }
            }));
 
            Task.WaitAll(taskLists.ToArray());
            stopWatch.Stop();

            this.BeginInvoke(new Action(delegate
            {
                this.label3.Text = "整体耗时" + stopWatch.Elapsed.TotalSeconds.ToString() + "秒";
                this.button3.Enabled = true;
            }));
        }

        /// <summary>
        /// 数据请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="requestContent"></param>
        /// <param name="methodName"></param>
        private void AskApi(string url,string requestContent, string methodName)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            string result = string.Empty;
            string haoshi = string.Empty;
            try
            {
                JObject jContent = JObject.Parse(requestContent);

                #region 必要值写入
                if (!string.IsNullOrEmpty(_registerNo))
                {
                    if (jContent["RegistNo"]!=null)
                    {
                        jContent["RegistNo"] = _registerNo;
                    }
                    if (jContent["registNo"] != null)
                    {
                        jContent["registNo"] = _registerNo;
                    }
                }

                if (!string.IsNullOrEmpty(_taskId))
                {
                    if (jContent["TaskId"] != null)
                    {
                        jContent["TaskId"] = _taskId;
                    }
                    if (jContent["taskId"] != null)
                    {
                        jContent["taskId"] = _taskId;
                    }
                }


                if (!string.IsNullOrEmpty(_claimNo))
                {
                    if (jContent["ClaimNo"] != null)
                    {
                        jContent["ClaimNo"] = _claimNo;
                    }
                }


                if (!string.IsNullOrEmpty(_compensateNo))
                {
                    if (jContent["CompensateNo"] != null)
                    {
                        jContent["CompensateNo"] = _compensateNo;
                    }
                }
                #endregion

                HttpClient client = new HttpClient();
                client.Timeout = new TimeSpan(0, 0, int.Parse(jContent["OutTime"].ToString()));
                HttpContent content = new StringContent(jContent.ToString());
                MediaTypeHeaderValue typeHeader = new MediaTypeHeaderValue("application/json");
                typeHeader.CharSet = "utf-8";
                content.Headers.ContentType = typeHeader;
                HttpResponseMessage hrm = client.PostAsync(url + "/" + methodName, content).Result;
                if (hrm.IsSuccessStatusCode)
                {
                    result = hrm.Content.ReadAsStringAsync().Result;
                    stopWatch.Stop();

                    #region 报案结果
                    if (methodName == "ReportCase" && !string.IsNullOrEmpty(result))
                    {
                        JObject jresult = JObject.Parse(result); 
                        if (jresult["ErrCode"].ToString() == "0" && jresult["RegistNo"] != null)
                        {
                            _registerNo = jresult["RegistNo"].ToString();
                        }
                    }
                    #endregion

                    #region 调度结果
                    //调度接口将改变后续所有请求的 RegistNo TaskId
                    if (methodName == "CaseDispatch" && !string.IsNullOrEmpty(result))
                    {
                        JObject jresult = JObject.Parse(result);
                        if (jresult["ErrCode"].ToString() == "0" && jresult["RegistNo"] != null && jresult["TaskId"] != null)
                        {
                            _registerNo = jresult["RegistNo"].ToString();
                            _taskId = jresult["TaskId"].ToString();

                            lock (lockObj)
                            {
                                using (FileStream fs = new FileStream(@".\RegisterNoAndPolicyNo\registerNo.txt", FileMode.Append))
                                {
                                    using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
                                    {
                                        sw.WriteLine(jresult["RegistNo"].ToString() + "=" + jresult["TaskId"].ToString() + "=" + jresult["ToName"].ToString()+"=" +jresult["ToCode"]);
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    #region 简易案件结果
                    if (methodName == "SimpleCase" && !string.IsNullOrEmpty(result))
                    {
                        JObject jresult = JObject.Parse(result);
                        if (jresult["ErrCode"].ToString() == "0" && jresult["ClaimNo"] != null && jresult["CompensateNo"] != null)
                        {
                            _claimNo = jresult["ClaimNo"].ToString();
                            _compensateNo = jresult["CompensateNo"].ToString();
                        }
                    }

                    #endregion

                    #region 立案结果
                    if (methodName == "Register" && !string.IsNullOrEmpty(result))
                    {
                        JObject jresult = JObject.Parse(result);
                        if (jresult["ErrCode"].ToString() == "0" && jresult["ClaimNo"] != null)
                        {
                            _claimNo = jresult["ClaimNo"].ToString();
                        }
                    }

                    #endregion

                    #region 理算核赔结果
                    if (methodName == "Compensate" && !string.IsNullOrEmpty(result))
                    {
                        JObject jresult = JObject.Parse(result);
                        if (jresult["ErrCode"].ToString() == "0" && jresult["CompensateNo"] != null)
                        {
                            _compensateNo = jresult["CompensateNo"].ToString();
                        }
                    }

                    #endregion
                }
                else
                {
                    result = hrm.StatusCode.ToString();
                }
            }
            //catch (WebException ex ) when(ex.Status==WebExceptionStatus.Timeout)
            catch(Exception ex)
            {
                LogManager.GetLogger("AskApi\r\n").Fatal(ex);
                stopWatch.Stop();
                result = ex.InnerException.InnerException.Message;
                if (string.IsNullOrWhiteSpace(result))
                {
                    result = ex.Message;
                }
            }
           
            haoshi = stopWatch.Elapsed.TotalSeconds.ToString();
            this.BeginInvoke(new InitListViewInfoDelegage(IninListViewInfo), new string[] { methodName, haoshi, result });
        }

        //异步ListView控件赋值
        delegate void InitListViewInfoDelegage(string methodName,string haoshi,string result);
        private void IninListViewInfo(string methodName, string haoshi, string result)
        {
            ListViewItem lvi = new ListViewItem();
            lvi.Text = methodName;
            lvi.SubItems.Add(haoshi);
            lvi.SubItems.Add(result);
            this.listView1.Items.Add(lvi);
        }

        /// <summary>
        /// ListView双击弹出结果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {
                ResponseDetailForm rdf = new ResponseDetailForm();
                rdf.result = this.listView1.SelectedItems[0].SubItems[2].Text;
                rdf.Show();
            }
        }

        /// <summary>
        /// →
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedIndex < 0 || _contentLists.Count<=0)
            {
                return;
            }

            if (this.groupBox3.Visible)
            {
                MessageBox.Show("请保存修改后的请求内容");
                return;
            }

            int index=this.listBox1.SelectedIndex;
            _dataLists.Add(_contentLists[index]);
            this.checkedListBox1.Items.Add(_contentLists[index].MethodName);

            _contentLists.RemoveAt(index);
            this.listBox1.Items.RemoveAt(index);
        }

        /// <summary>
        /// All→
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            if (_contentLists.Count <= 0)
            {
                return;
            }

            if (this.groupBox3.Visible)
            {
                MessageBox.Show("请保存修改后的请求内容");
                return;
            }

            foreach (var item in _contentLists)
            {
                _dataLists.Add(item);
                this.checkedListBox1.Items.Add(item.MethodName);
            }

            _contentLists.Clear();
            this.listBox1.Items.Clear();
        }

        /// <summary>
        /// ←
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            if (checkedListBox1.SelectedIndex < 0 || _dataLists.Count <= 0)
            {
                return;
            }

            int index=this.checkedListBox1.SelectedIndex;

            _contentLists.Add(_dataLists[index]);
            this.listBox1.Items.Add(_dataLists[index].MethodName);

            _dataLists.RemoveAt(index);
            this.checkedListBox1.Items.RemoveAt(index);
        }

        /// <summary>
        /// ←All
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            if (_dataLists.Count <= 0)
            {
                return;
            }

            foreach (var item in _dataLists)
            {
                _contentLists.Add(item);
                this.listBox1.Items.Add(item.MethodName);
            }

            _dataLists.Clear();
            this.checkedListBox1.Items.Clear();
        }

        /// <summary>
        /// ↑
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button8_Click(object sender, EventArgs e)
        {
            if (checkedListBox1.SelectedIndex <= 0 || _dataLists.Count <= 0)
            {
                return;
            }
            int index = checkedListBox1.SelectedIndex;
            var tmp = _dataLists[index - 1];
            _dataLists[index - 1] = _dataLists[index];
            _dataLists[index] = tmp;

            var tmpCheckBox = checkedListBox1.Items[index - 1];
            checkedListBox1.Items[index - 1] = checkedListBox1.Items[index];
            checkedListBox1.Items[index] = tmpCheckBox;

         
        }

        /// <summary>
        /// ↓
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button9_Click(object sender, EventArgs e)
        {
            if (checkedListBox1.SelectedIndex < 0 || _dataLists.Count <= 0 || checkedListBox1.SelectedIndex >= _dataLists.Count-1)
            {
                return;
            }

            int index = checkedListBox1.SelectedIndex;
            var tmp = _dataLists[index + 1];
            _dataLists[index + 1] = _dataLists[index];
            _dataLists[index] = tmp;

            var tmpCheckBox = checkedListBox1.Items[index + 1];
            checkedListBox1.Items[index + 1] = checkedListBox1.Items[index];
            checkedListBox1.Items[index] = tmpCheckBox;
        }

        /// <summary>
        /// All 异步并发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (_dataLists.Count<=0)
            {
                return;
            }

            bool isChecked = this.checkBox1.Checked;

            for (int i = 0; i < checkedListBox1.Items.Count; i++)
            {
                checkedListBox1.SetItemChecked(i,isChecked);
            }
        }

        /// <summary>
        /// 双击修改请求参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                if (listBox1.SelectedIndex < 0)
                {
                    return;
                }
                _updateIndex = listBox1.SelectedIndex;
                this.groupBox2.Visible = false;
                this.groupBox3.Visible = true;
                this.richTextBox1.Text = JObject.Parse(_contentLists[_updateIndex].RequestContent).ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("模板参数非标准json");
            }
          
        }

        /// <summary>
        /// 保存修改后的结果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button10_Click(object sender, EventArgs e)
        {
            _contentLists[_updateIndex].RequestContent = this.richTextBox1.Text;
            this.richTextBox1.Text = string.Empty;
            _updateIndex = -1;
            this.groupBox2.Visible = true;
            this.groupBox3.Visible = false;
        }

        /// <summary>
        /// 选中comboBox1下拉框时候，过滤弹窗中的接口集合
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var urlAddress = this.comboBox1.Text;
            _currentUrl = urlAddress;
        }
    }
}
